// /////////////////////////////////////////////////////////////////////////////
//
// Name:            AssetGroup.cpp
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Represents a collection of assets (meshes, textures, etc).
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

// Include files
#include "AssetGroup.h"
#include "GameManager.h"


// AssetGroup class
// Static variables.
u32 AssetGroup::mIDCount = 0;

// AssetGroup constructor.
AssetGroup::AssetGroup(const std::string &name, const std::string &dirName)
: mName(name)
{
    mID = mIDCount++;
    mBaseDir = (GameManager::Instance()->getDevice()->getFileSystem()
                 ->getAbsolutePath(dirName.c_str())).c_str();

    init();
}

// AssetGroup deconstructor.
AssetGroup::~AssetGroup()
{
    clear();
}

// Initialises the AssetGroup.
void AssetGroup::init()
{
    GameManager::Instance()->getAssetManager()->getAssetProcessors(this, mAssetProcessors);
    loadAssets();
}

// Clears the AssetGroup.
void AssetGroup::clear()
{
    // Remove all assets from this asset group.
    removeAssets();

    // Remove all asset processors from this asset group.
    std::vector<AssetProcessor*>::iterator it;
    for(it = mAssetProcessors.begin(); it != mAssetProcessors.end(); it++)
      delete (*it);

    mAssetProcessors.clear();
}

// Gets the ID of the AssetGroup.
u32 AssetGroup::getID() const
{
    return mID;
}

// Gets the name of the AssetGroup.
const std::string& AssetGroup::getName() const
{
    return mName;
}

// Gets the base directory of the AssetGroup.
const std::string& AssetGroup::getBaseDir() const
{
    return mBaseDir;
}

// Gets the AssetProcessor with the given base name.
AssetProcessor* AssetGroup::getAssetProcessor(const std::string &baseName)
{
    // Try to find the AssetProcessor.
    vector<AssetProcessor*>::iterator it;

    for(it = mAssetProcessors.begin(); it != mAssetProcessors.end(); it++)
    {
       AssetProcessor *processor = *it;

       if(processor->getBaseName() == baseName)
         return processor;
    }

    // We didn't find the AssetProcessor and thus return a NULL value.
    return NULL;
}

// Loads the meshes associated with this asset group.
void AssetGroup::loadAssets()
{
    vector<AssetProcessor*>::iterator it;

    for(it = mAssetProcessors.begin(); it != mAssetProcessors.end(); it++)
      (*it)->loadAssets();
}

// Reloads the asset with the given name.
bool AssetGroup::reloadAsset(const std::string &name)
{
   // Determine the asset type we're dealing with.
    std::string assetType;
    size_t pos;

    pos = name.find("/");
    if(pos == std::string::npos)
    {
       pos = name.find("\"");
       if(pos == std::string::npos)
       {
          return false;
       }
    }

    assetType = name.substr(0, pos);

    // Determine the asset name.
    std::string assetName = name.substr(pos+1, name.size()-pos);

    // Reload the asset.
    vector<AssetProcessor*>::iterator it;

    for(it = mAssetProcessors.begin(); it != mAssetProcessors.end(); it++)
    {
        AssetProcessor *processor = *it;

        if(processor->getBaseName() == assetType)
        {
            processor->reloadAsset(assetName);
            break;
        }
    }

    // We couldn't reload the asset.
    return false;
}

// Reloads all assets in this asset group.
void AssetGroup::reloadAssets()
{
    vector<AssetProcessor*>::iterator it;

    for(it = mAssetProcessors.begin(); it != mAssetProcessors.end(); it++)
      (*it)->reloadAssets();
}

// Removes the asset with the given name.
bool AssetGroup::removeAsset(const std::string &name)
{
    // Determine the asset type we're dealing with.
    std::string assetType;
    size_t pos;

    pos = name.find("/");
    if(pos == std::string::npos)
    {
       pos = name.find("\"");
       if(pos == std::string::npos)
       {
          return false;
       }
    }

    assetType = name.substr(0, pos);

    // Determine the asset name.
    std::string assetName = name.substr(pos+1, name.size()-pos);

    // Remove the asset.
    vector<AssetProcessor*>::iterator it;

    for(it = mAssetProcessors.begin(); it != mAssetProcessors.end(); it++)
    {
        AssetProcessor *processor = *it;

        if(processor->getBaseName() == assetType)
        {
            processor->removeAsset(assetName);
            break;
        }
    }

    // We failed to remove the asset.
    return false;
}

// Removes all assets in this asset group.
void AssetGroup::removeAssets()
{
    vector<AssetProcessor*>::iterator it;

    for(it = mAssetProcessors.begin(); it != mAssetProcessors.end(); it++)
      (*it)->removeAssets();
}

// End of File
